﻿namespace IBTrader.Charts.Windows
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Shapes;

    class CanvasGraphics : BaseGraphics, IGraphics
    {
        private readonly Canvas canvas;
        internal CanvasGraphics(Canvas canvas)
        {
            this.canvas = canvas;
        }
        internal void Draw(IEnumerable<IChart> charts, double width, double height)
        {
            canvas.Children.Clear();
            canvas.Width = width;
            canvas.Height = height;
            base.Draw(this, charts, width, height);
        }
        public void FillPolygon(System.Drawing.SolidBrush brush, System.Drawing.PointF[] points)
        {
            Add(Filling<Polyline>(brush), points);
        }

        public void DrawLines(System.Drawing.Pen pen, params System.Drawing.PointF[] points)
        {
            Add(Drawing<Polyline>(pen), points);
        }

        public void DrawString(string txt, System.Drawing.Font font, System.Drawing.SolidBrush solidBrush, System.Drawing.PointF point)
        {
            Add(new TextBlock() { Text = txt, FontSize = font.Size, Foreground = new SolidColorBrush(Convert(solidBrush.Color))}, point);
        }

        public void FillRectangle(System.Drawing.SolidBrush brush, System.Drawing.RectangleF rectangle)
        {
            Add(Filling<Rectangle>(brush), rectangle);
        }

        public void DrawRectangle(System.Drawing.Pen pen, System.Drawing.Rectangle rectangle)
        {
            Add(Drawing<Rectangle>(pen), rectangle);
        }

        public void FillPie(System.Drawing.SolidBrush brush, System.Drawing.Rectangle rectangle, int startAngle, int sweepAngle)
        {
            Add(Filling<Ellipse>(brush), rectangle);
        }

        public void DrawPie(System.Drawing.Pen pen, System.Drawing.RectangleF rectangle, int startAngle, int sweepAngle)
        {
            Add(Drawing<Ellipse>(pen), rectangle);
        }

        private void Add(Polyline shape, System.Drawing.PointF[] points)
        {
            points.ToList().ForEach(point => shape.Points.Add(new Point(point.X, point.Y)));
            canvas.Children.Add(shape);
        }

        private void Add(Shape shape, System.Drawing.RectangleF rectangle)
        {
            shape.Width = rectangle.Width;
            shape.Height = rectangle.Height;
            Add(shape, new System.Drawing.PointF(rectangle.X, rectangle.Y));
        }

        private void Add(FrameworkElement element, System.Drawing.PointF point)
        {
            Canvas.SetTop(element, point.X);
            Canvas.SetLeft(element, point.Y);
            canvas.Children.Add(element);
        }

        private static T Drawing<T>(System.Drawing.Pen pen) where T : Shape, new()
        {
            var shape = new T();
            shape.Stroke = new SolidColorBrush(Convert(pen.Color));
            shape.StrokeThickness = pen.Width;
            return shape;
        }

        private static T Filling<T>(System.Drawing.SolidBrush brush) where T : Shape, new()
        {
            var shape = new T();
            shape.Fill = new SolidColorBrush(Convert(brush.Color));
            return shape;
        }

        private static Func<System.Drawing.Color, Color> Convert = color => Color.FromArgb(color.A, color.R, color.G, color.B);
    }
}